#include "Parser.h"

#include "net/instaweb/util/public/google_message_handler.h"

void CParser::Expose(void)
{
  py::enum_<ContentType::Type>("ContentType")
    .value("html", ContentType::kHtml)
    .value("xhtml", ContentType::kXhtml)
    .value("cehtml", ContentType::kCeHtml)  // See http://en.wikipedia.org/wiki/CE-HTML
    .value("javascript", ContentType::kJavascript)
    .value("css", ContentType::kCss)
    .value("text", ContentType::kText)
    .value("xml", ContentType::kXml)
    .value("png", ContentType::kPng)
    .value("gif", ContentType::kGif)
    .value("jpeg", ContentType::kJpeg)
    ;

  py::class_<CParser, boost::noncopyable>("HtmlParser", py::no_init)
    .def(py::init<const std::string, const std::string, ContentType::Type>(
          (py::arg("url")=std::string(),
           py::arg("id")=std::string(),
           py::arg("type")=ContentType::kHtml)))

    .add_property("document", &CParser::GetDocument)

    .add_property("url", &CParser::GetUrl)
    .add_property("id", &CParser::GetId)
    .add_property("linenum", &CParser::GetLineNumber)

    .def("reset", &CParser::Reset, "Reset this instance. Loses all unprocessed data.")
    .def("feed", &CParser::Feed, "Feed some data to the parser.")
    .def("close", &CParser::Close, "Handle the remaining data.")
    .def("flush", &CParser::Flush, "Flush the currently queued events through the filters.")
    ;
}

static const ContentType *ContentTypes[] = {
  &kContentTypeHtml, &kContentTypeXhtml, &kContentTypeCeHtml,
  &kContentTypeJavascript, &kContentTypeCss, &kContentTypeText, &kContentTypeXml,
  &kContentTypePng, &kContentTypeGif, &kContentTypeJpeg
};

CParser::CParser(const std::string url, const std::string id, ContentType::Type type)
  : m_message_handler(new GoogleMessageHandler()), m_type(type)
{
  m_html_parser.reset(new HtmlParse(m_message_handler.get()));

  if (id.empty())
  {
    if (type != ContentType::kHtml)
    {
      m_html_parser->StartParseWithType(url, *ContentTypes[type]);      
    }
    else
    {
      m_html_parser->StartParse(url);
    }
  }
  else
  {
    m_html_parser->StartParseId(url, id, *ContentTypes[type]);
  }
}

CHtmlDocument CParser::GetDocument(void) const
{
  return CHtmlDocument(m_html_parser.get());
}

void CParser::Reset(void)
{
  std::auto_ptr<HtmlParse> html_parser(new HtmlParse(m_message_handler.get()));

  html_parser->StartParseId(m_html_parser->url(), m_html_parser->id(), *ContentTypes[m_type]);

  m_html_parser = html_parser;
}
